package com.swjd.sort;

import java.util.Arrays;

/**
 * 基数排序
 * Created by Administrator on 2021/9/29.
 */
public class RadixSort {
    public static void main(String[] args) {
/*        int arr[] = {53, 3, 542, 748, 14, 214};
        radixSort(arr);*/

        //测试基数排序速度  8万个数据测试
        long start = System.currentTimeMillis();
        int[] arr = new int[80000];
        for (int i = 0; i < 80000; i++) {
            arr[i] = (int) (Math.random() * 8000000);//生成[0,8000000)
        }
        int temp[] = new int[arr.length];
        radixSort(arr);
        long end = System.currentTimeMillis();
        System.out.println("运行时长：" + (end - start) + "ms");
    }

    public static void radixSort(int[] arr) {
        //得到原数组中最大值
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        //得出最大的位数 把最大值变成字符串然后判断字符串长度就是位数
        int maxLength = (max + "").length();


        //第一轮排序 对个位数进行排序
        //定义二维数组，代表十个桶 每个桶给总数据的大小
        int[][] bucket = new int[10][arr.length];

        //记录各个桶中有多少个数据
        int[] elm = new int[10];

        //进行循环操作，有多少位就循环多少次
        for (int i = 0, n = 1; i < maxLength; i++, n = n * 10) {
            //针对元素位数进行指定取出位数
            for (int j = 0; j < arr.length; j++) {
                //取出每个元素的相应位数位
                int num = arr[j] / n % 10;
                //放入对应的桶中 第num个桶  放到第num个桶的第elm[num]个数据
                bucket[num][elm[num]] = arr[j];
                //elm[桶位置]代表是一个指针，记录元素 记录一个之后就需要往上移
                elm[num]++;
            }
            //按照桶的顺序放入原数组
            int index = 0;
            //遍历每一个桶，并将桶中数据放入原数组
            for (int k = 0; k < 10; k++) {
                //如果桶中有数据，才放入原数组
                if (elm[k] != 0) {
                    //循环这个桶 elm[k]代表第k个桶中放了多少个数据
                    for (int l = 0; l < elm[k]; l++) {
                        //取出元素放入arr 将第k个桶的第l个元素放进原数组
                        arr[index] = bucket[k][l];
                        index++;
                    }
                }
                //放入原数组后，将临时储存数量的数组清零
                elm[k] = 0;
            }
//            System.out.println(Arrays.toString(arr));
        }
    }
}